﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;

namespace PageAdmin.Utils
{
    /// <summary>
    /// 基础帮助类
    /// </summary>
    public class IEnumerableHelper
    {
        /// <summary>
        /// 字典转键值对
        /// </summary>
        /// <param name="keyRegular"></param>
        /// <returns></returns>
        public static NameValueCollection FormatNameValueCollection(Dictionary<string, dynamic> dictionary)
        {
            NameValueCollection nameValueCollection = new NameValueCollection();
            foreach (var item in dictionary)
            {
                nameValueCollection[item.Key] = StringHelper.Format<string>(item.Value);
            }
            return nameValueCollection;
        }

        /// <summary>
        /// 集合转字典
        /// </summary>
        /// <param name="nameValueCollection"></param>
        /// <returns></returns>
        public static Dictionary<string, string> FormatDictionary(NameValueCollection nameValueCollection)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
            foreach (string key in nameValueCollection)
            {
                if (!dic.ContainsKey(key))
                {
                    dic.Add(key, nameValueCollection[key]);
                }
            }
            return dic;
        }

        /// <summary>
        /// 动态类型集合分页
        /// </summary>
        /// <param name="dataList"></param>
        /// <param name="pageInfo"></param>
        /// <returns></returns>
        public static IEnumerable<dynamic> Split(IEnumerable<dynamic> dataList, PageInfo pageInfo)
        {
            int recordCount = dataList.Count();
            int currentPage = pageInfo.CurrentPage;
            int pageSize = pageInfo.PageSize;
            int pageCount = (recordCount % pageSize == 0) ? (recordCount / pageSize) : (recordCount / pageSize + 1);
            pageInfo.RecordCount = recordCount;
            pageInfo.PageCount = pageCount;
            return dataList.Skip((currentPage - 1) * pageSize).Take(pageSize);
        }

        /// <summary>
        /// 对IEnumerable<T></T></typeparam>进行分页
        /// </summary>
        /// <param name="dataList"></param>
        /// <param name="pageInfo"></param>
        /// <returns></returns>
        public static IEnumerable<T> Split<T>(IEnumerable<T> dataList, PageInfo pageInfo) where T : class
        {
            int recordCount = dataList.Count();
            int currentPage = pageInfo.CurrentPage;
            int pageSize = pageInfo.PageSize;
            int pageCount = (recordCount % pageSize == 0) ? (recordCount / pageSize) : (recordCount / pageSize + 1);
            pageInfo.RecordCount = recordCount;
            pageInfo.PageCount = pageCount;
            return dataList.Skip((currentPage - 1) * pageSize).Take(pageSize);
        }


        /// <summary>
        /// 获取当前父级节点的value集合
        /// </summary>
        /// <param name="sourceList"></param>
        /// <param name="id"></param>
        /// <param name="includeSelf"></param>
        /// <returns></returns>
        public static IEnumerable<int> GetParentValueList<T>(IEnumerable<T> sourceList, int curentId, bool includeSelf = true) where T : TreeOptionsItem
        {
            HashSet<int> valueList = new HashSet<int>();
            T data = sourceList.Where(c => c.value == curentId).FirstOrDefault();
            if (data == null)
            {
                return valueList;
            }
            if (includeSelf)
            {
                valueList.Add(curentId);
            }
            int parentId = data.parentValue;
            if (parentId == 0)
            {
                return valueList;
            }
            T parentData = sourceList.Where(c => c.value == parentId).FirstOrDefault();
            if (parentData != null)
            {
                IEnumerable<int> parentIds = GetParentValueList(sourceList, parentData.value, false);
                if (parentIds.Count() <= 0)
                {
                    valueList.Add(parentData.value);
                }
                else
                {
                    valueList.Add(parentData.value);
                    foreach (int id in parentIds)
                    {
                        valueList.Add(id);
                    }
                }
            }
            return valueList.Reverse().ToList();
        }

        /// <summary>
        /// 获取当前父级节点的label集合
        /// </summary>
        /// <param name="soruceList">未转换为树形的集合</param>
        /// <param name="id"></param>
        /// <param name="includeSelf"></param>
        /// <returns></returns>
        public static IEnumerable<string> GetParentLabelList<T>(IEnumerable<T> soruceList, int curentId, bool includeSelf = true) where T : TreeOptionsItem
        {
            ICollection<string> labelList = new List<string>();
            T data = soruceList.Where(c => c.value == curentId).FirstOrDefault();
            if (data == null)
            {
                return labelList;
            }
            if (includeSelf)
            {
                labelList.Add(data.label);
            }
            int parentId = data.parentValue;
            if (parentId == 0)
            {
                return labelList;
            }
            T parentData = soruceList.Where(c => c.value == parentId).FirstOrDefault();
            if (parentData != null)
            {
                IEnumerable<string> parentLabels = GetParentLabelList(soruceList, parentData.value, false);
                if (parentLabels.Count() <= 0)
                {
                    labelList.Add(parentData.label);
                }
                else
                {
                    labelList.Add(parentData.label);
                    foreach (string label in parentLabels)
                    {
                        labelList.Add(label);
                    }
                }
            }
            return labelList.Reverse().ToList();
        }


        /// <summary>
        /// 获取所有的子级节点的Value集合
        /// </summary>
        /// <param name="soruceList">未转换的集合</param>
        /// <param name="curentId"></param>
        /// <param name="incluseSelf">是否包含当前id</param>
        /// <returns></returns>
        public static IEnumerable<int> GetChildrenValueList<T>(IEnumerable<T> soruceList, int curentId, bool includeSelf = true) where T : TreeOptionsItem
        {
            HashSet<int> valueList = new HashSet<int>();
            T data = soruceList.Where(c => c.value == curentId).FirstOrDefault();
            if (data == null)
            {
                return valueList;
            }
            if (includeSelf)
            {
                valueList.Add(data.value);
            }
            IEnumerable<T> newDataList = soruceList.Where(c => c.parentValue == curentId);
            foreach (T item in newDataList)
            {
                IEnumerable<int> childrenIds = GetChildrenValueList(soruceList, item.value, false);
                if (childrenIds.Count() <= 0)
                {
                    valueList.Add(item.value);
                }
                else
                {
                    valueList.Add(item.value);
                    foreach (int id in childrenIds)
                    {
                        valueList.Add(id);
                    }
                }
            }
            return valueList;
        }


        /// <summary>
        /// 普通列表转换为树形列表，主要用于前端的级联选择器。
        /// </summary>
        /// <param name="sourceList">普通的列表数据</param>
        /// <returns></returns>
        public static IEnumerable<T> TransformTreeOptions<T>(IEnumerable<T> sourceList) where T : TreeOptionsItem
        {
            var list = TransformTreeOptionsItem(sourceList, 0);
            if (list == null)
            {
                list = new List<T>(); //必须做这个处理，否则前端返回null绑定会报错
            }
            return list;
        }

        /// <summary>
        /// 递归转换
        /// </summary>
        /// <param name="sourceList"></param>
        /// <param name="parentValue"></param>
        /// <returns></returns>
        private static IEnumerable<T> TransformTreeOptionsItem<T>(IEnumerable<T> sourceList, int parentValue) where T : TreeOptionsItem
        {
            List<T> newDataSource = sourceList.ToList();
            newDataSource.RemoveAll(c => c.parentValue == parentValue);
            List<T> currentList = sourceList.Where(c => c.parentValue == parentValue).ToList();
            if (currentList.Count() == 0)
            {
                return null; //必须返回null，否则返回[]，用于前端组件时候会无法选择最后一级数据
            }
            foreach (T item in currentList)
            {
                item.children = TransformTreeOptionsItem(newDataSource, item.value);
            }
            return currentList;
        }
    }
}